package geographer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import mvc.SelectionView;

/**
 * Project #3
 * CS 2334, 010
 * 03/26/2014
 * <P>
 * This class represents the city class. It inherits from GeographicRegion.
 * </P>
 * @version 3.0
 */
public class City extends GeographicRegion implements Serializable {
	
	/**
	 * THe unique serial id
	 */
	private static final long serialVersionUID = 1L;

	/*Latitude of the City*/
	private String latitude;
	
	/*Longitude of the City*/
	private String longitude;
	
	/*Elevation of the City*/
	private String elevation;
	
	/*The Country the city belongs to*/
	private String country;

	
	/**
	 * Constructor for the city
	 * <P>
	 * The constructor for the city
	 * </P>
	 * @params	data	Data array passed into the constructor
	 */
	public City(String... data) {
		
		//Send the data to the constructor of the super class
		super(data[0], data[1], data[2]);
		
		country = data[3]; //Assign the value of country to the corresponding value of the data array
		
		//Decide if the additional values need to be assigned based on length of data array
		if(data.length > 6)
		{
			latitude = data[4];
			longitude = data[5];
			elevation = data[6];
		}//end if
	}//end City constructor
	
	public void edit(String[] data)
	{
		super.edit(data[0], data[1], data[2]);
		country = data[3];
		if(data.length > 6)
		{
			latitude = data[4];
			longitude = data[5];
			elevation = data[6];
		}
	}
	
	/**
	 * The accessor for the latitude of this city.
	 * @return latitude  The latitude of the city
	 */
	public String getLat()
	{
		return latitude;
	}//end getLat
	
	/**
	 * The accessor for the longitude of this city
	 * @return longitude    The longitude of the city
	 */
	public String getLon()
	{
		return longitude;
	}//end getLon

	/**
	 * Gets the region above this particular <code>City</code>
	 * <P>
	 * Algorithm:<br>
	 * 1. Return the value of the super region <br>
	 * </P>
	 * @return       country  The super reigon associated with this city.
	 * <dt><b>Conditions:</b>
	 * <dd>POST -          The correct super region value is returned.
	 */
	public String getSuperRegion(){
		return country;
	}//end getSuperRegion
	
	public String getElevation(){
		return elevation;
	}
	
	/**
	 * Returns the contents of the <code>City</code> object as a string.
	 * <P>
	 * Algorithm:<br>
	 * 1. Create a string containing all values within this object <br>
	 * 2. Return the string<br>
	 * </P>
	 *@return   String A string containing all information in the <code>City</code> object.
	 * <dt><b>Conditions:</b>
	 * <dd>POST -          A String continaing all information for this object is returned.
	 */
	@Override
	public String toString() {
		return  this.getName() +", "+ 
				this.getArea() +", "+ 
				this.getPopulation() +", "+
				this.country + ((latitude != null) ? ", "+
				(latitude +", "+
				 longitude +", "+
				 elevation):"");
	}//end toString
	
	/**
	 * City comparator comparing elevations of two <code>City</code> objects
	 * <P>
	 * Algorithm:<br>
	 * 1. Check if both elevations have a value. <br>
	 * 2. Check if one elevation has a value and the other does not<br>
	 * 3. Repeat 2. with reversed objects<br>
	 * </P>
	 * @params	o1, o2	Cities to compare
	 * @return	  int Integer that states the comparison value between the objects
	 * <dt><b>Conditions</b>
	 * <dd> PRE -            Both <code>City</code> objects are not null
	 * <dd> POST -           A comparison value of the two objects has been returned.
	 */
	static final Comparator<String> EL = new Comparator<String>(){
		@Override
		public int compare(String c1, String c2) {
			City o1 = (City) GeoGrapher.data.getRegions().get(c1);
			City o2 = (City) GeoGrapher.data.getRegions().get(c2);
			
			if(o1.elevation == null && o2.elevation == null)
				return 0; //Return if objects are equal
			else if(o1.elevation == null && o2.elevation != null)
				return 1; //Return if o1 is greater than o2
			else if(o1.elevation != null && o2.elevation == null)
				return -1; //Return if o1 is less than o2
			return Long.valueOf(o2.elevation).compareTo(Long.valueOf(o1.elevation));
		}
	};//end Comparator EL
	
	/**
	 * City comparator comparing latitudes of two <code>City</code> objects
	 * <P>
	 * Algorithm:<br>
	 * 1. Check if both latitudes have a value. <br>
	 * 2. Check if one latitude has a value and the other does not<br>
	 * 3. Repeat 2. with reversed objects<br>
	 * 4. Assign values for hemispheres for further comparison<br>
	 * 5. Repeat comparison process for hemisphere values<br>
	 * </P>
	 * @params	o1, o2	Cities to compare
	 * @return	  int Integer that states the comparison value between the objects
	 * <dt><b>Conditions</b>
	 * <dd> PRE -            Both <code>City</code> objects are not null
	 * <dd> POST -           A comparison value of the two objects has been returned.
	 */
	static final Comparator<String> LA = new Comparator<String>(){
		@Override
		public int compare(String c1, String c2) {
			City o1 = (City) GeoGrapher.data.getRegions().get(c1);
			City o2 = (City) GeoGrapher.data.getRegions().get(c2);
			if(o1.latitude == null && o2.latitude == null)
				return 0; //Return if the objects are equal
			else if(o1.latitude == null && o2.latitude != null)
				return 1;//Return if o1 is greater that o2
			else if(o1.latitude != null && o2.latitude == null)
				return -1;//Return if o2 is greater than o1
			
			//Split the string to compare hemispheres
			char hem1 = o1.latitude.charAt(0),
				 hem2 = o2.latitude.charAt(0);
			
			//Split remaining string to assign latitudes
			Double la1 = Double.valueOf(o1.latitude.substring(1)),
				   la2 = Double.valueOf(o2.latitude.substring(1));
			
			if(hem1 == hem2)
				return la1.compareTo(la2); //Compare latitudes if hemispheres are equal
			else if(hem1 == 'N')
				return -1; //Return if o1 is greater than o2
			else
				return 1;//Return if o2 is greater than o1
		}
	};//end LA comparator
	
	/**
	 * City comparator comparing longitudes of two <code>City</code> objects
	 * <P>
	 * Algorithm:<br>
	 * 1. Check if both longitude have a value. <br>
	 * 2. Check if one longitude has a value and the other does not<br>
	 * 3. Repeat 2. with reversed objects<br>
	 * 4. Split the remaining String into pieces to compare hemispheres
	 * 5. Compare hemispheres
	 * </P>
	 * @params	o1, o2	Cities to compare
	 * @return	  int Integer that states the comparison value between the objects
	 * <dt><b>Conditions</b>
	 * <dd> PRE -            Both <code>City</code> objects are not null
	 * <dd> POST -           A comparison value of the two objects has been returned.
	 */
	static final Comparator<String> LO = new Comparator<String>(){
		@Override
		public int compare(String c1, String c2) {
			City o1 = (City) GeoGrapher.data.getRegions().get(c1);
			City o2 = (City) GeoGrapher.data.getRegions().get(c2);
			if(o1.longitude == null && o2.longitude == null)
				return 0;//Return if the objects are equal
			else if(o1.longitude == null && o2.longitude != null)
				return 1;//Return if o1 is greater than o2
			else if(o1.longitude != null && o2.longitude == null)
				return -1;//Return if o2 is greater than o1
			
			//Split String to compare hemispheres
			char hem1 = o1.longitude.charAt(0),
				 hem2 = o2.longitude.charAt(0);
			
			//Assign values for the longitudes
			Double la1 = Double.valueOf(o1.longitude.substring(1)),
				   la2 = Double.valueOf(o2.longitude.substring(1));
			
			if(hem1 == hem2)
				return la1.compareTo(la2);//If hemisphere is equal, compare longitudes
			else if(hem1 == 'E')
				return -1;//Return if o1 is greater than o2
			else
				return 1;//Return if o2 is greater than o2
		}
	};//End LO Comparator
}//end City class
